<!DOCTYPE html>
<html lang="zh-cn">


<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
  <meta name="theme-color" content="#202020"/>
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  
    <meta name="keywords" content="设计模式," />
  

  
    <meta name="description" content="我在时间的长河中流浪，寻找一个有你的地方" />
  
  
  
    <link rel="icon" type="image/x-icon" href="https://cdn.jsdelivr.net/gh/haige2486/CDN@1.0/images/favicon.ico">
  
  <title>future设计模式 [ 海哥のBlog ]</title>
  
    <!-- stylesheets list from config.yml -->
    
      <link rel="stylesheet" href="//cdn.bootcss.com/pure/1.0.0/pure-min.css">
    
      <link rel="stylesheet" href="/css/xoxo.css">
    
      <link rel="stylesheet" href="/css/keyframe.css">
    
  
  <script src="https://cdn.jsdelivr.net/npm/pjax/pjax.js"></script>
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<meta name="generator" content="Hexo 4.2.0"></head>

<body>
  <div class="nav-container">
    <nav class="home-menu pure-menu pure-menu-horizontal">
  <a class="pure-menu-heading" href="/">
    
      <img class="avatar" src="https://cdn.jsdelivr.net/gh/haige2486/CDN@1.0/images/custom/avatar.png">
    
    <span class="title">海哥のBlog</span>
  </a>

  <ul class="pure-menu-list clearfix">
      
          
            <li class="pure-menu-item"><a href="/" class="pure-menu-link">首页</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/archives" class="pure-menu-link">归档</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/tags" class="pure-menu-link">标签</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/categories" class="pure-menu-link">分类</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/search" class="pure-menu-link">搜索</a></li>
          
      
  </ul>
   
</nav>
  </div>

  <div class="container" id="content-outer">
    <div class="inner" id="content-inner">
      <div class="post-container">
  <article class="post" id="post">
    <header class="post-header text-center">
      <h1 class="title">
        future设计模式
      </h1>
      <span>
        
        <time class="time" datetime="2020-08-12T07:49:00.000Z">
          2020-08-12
        </time>
        
      </span>
      
      <span class="slash">/</span>
      <span class="post-meta">
        <span class="post-tags">
          <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" rel="tag">设计模式</a></li></ul>
        </span>
      </span>
      
      <span class="slash">/</span>
      <span class="read" span id="busuanzi_container_page_pv">
        本文总阅读量：<span id="busuanzi_value_page_pv"></span>次
      </span>
    </header>

    <div class="post-content">
      <p>__*注意：通过类属性持有一个泛型来实现订阅者模式 __</p>
<h2 id="future的简单实现"><a href="#future的简单实现" class="headerlink" title="future的简单实现"></a>future的简单实现</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.test.future;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.atomic.AtomicBoolean;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.atomic.AtomicReference;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FutureAction</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; <span class="function">Future&lt;T&gt; <span class="title">invoke</span><span class="params">(Callable&lt;T&gt; callable)</span></span>&#123;</span><br><span class="line">        <span class="comment">//4. 创建结果持有属性</span></span><br><span class="line">        AtomicReference&lt;T&gt; result = <span class="keyword">new</span> AtomicReference&lt;&gt;();</span><br><span class="line">        <span class="comment">//4. 创建结果持有属性</span></span><br><span class="line">        AtomicBoolean finished = <span class="keyword">new</span> AtomicBoolean(<span class="keyword">false</span>);</span><br><span class="line">        <span class="comment">//1. 开启一个线程异步执行业务逻辑</span></span><br><span class="line">        Thread t = <span class="keyword">new</span> Thread(()-&gt;&#123;</span><br><span class="line">            T value = callable.action();</span><br><span class="line">            result.set(value);</span><br><span class="line">            finished.set(<span class="keyword">true</span>);</span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="comment">//2. 由于要将执行结果以Future返回，所以该方法内部应持有一个Future</span></span><br><span class="line">        Future&lt;T&gt; future = <span class="keyword">new</span> Future&lt;T&gt;() &#123;</span><br><span class="line">            <span class="comment">//3. 内部类可以取到外面的属性，所有在外面创建Atomic类型</span></span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> T <span class="title">get</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                <span class="keyword">return</span> result.get();</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isDone</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                <span class="keyword">return</span> finished.get();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="comment">//5. 执行线程</span></span><br><span class="line">        t.start();</span><br><span class="line">        <span class="keyword">return</span> future;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Future</span>&lt;<span class="title">T</span>&gt;</span>&#123;</span><br><span class="line">        <span class="function">T <span class="title">get</span><span class="params">()</span></span>;</span><br><span class="line">        <span class="function"><span class="keyword">boolean</span> <span class="title">isDone</span><span class="params">()</span></span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//外部业务逻辑执行接口</span></span><br><span class="line">    <span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Callable</span>&lt;<span class="title">T</span>&gt;</span>&#123;</span><br><span class="line">        <span class="function">T <span class="title">action</span><span class="params">()</span></span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> InterruptedException </span>&#123;</span><br><span class="line">        Future&lt;String&gt; future = invoke(() -&gt; &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                Thread.sleep(<span class="number">1000L</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="string">"I am Finished."</span>;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">                <span class="keyword">return</span> <span class="string">"I am Error."</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        System.out.println(future.get());</span><br><span class="line">        System.out.println(future.get());</span><br><span class="line">        System.out.println(future.get());</span><br><span class="line">        Thread.sleep(<span class="number">2000L</span>);</span><br><span class="line">        System.out.println(future.get());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//：~执行结果为</span></span><br><span class="line"><span class="comment">//null</span></span><br><span class="line"><span class="comment">//null</span></span><br><span class="line"><span class="comment">//null</span></span><br><span class="line"><span class="comment">//I am Finished.</span></span><br></pre></td></tr></table></figure>

<p>这个实现虽然不会阻塞线程但是对于结果我们不能实时得到，为了实现实时拿到结果，可以使用订阅者模式，在结果产生了，异步线程就通知你结果。改造如下</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.test.future;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.atomic.AtomicBoolean;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.atomic.AtomicReference;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FutureAction</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; <span class="function">Future&lt;T&gt; <span class="title">invoke</span><span class="params">(Callable&lt;T&gt; callable)</span></span>&#123;</span><br><span class="line">        <span class="comment">//4. 创建结果持有属性</span></span><br><span class="line">        AtomicReference&lt;T&gt; result = <span class="keyword">new</span> AtomicReference&lt;&gt;();</span><br><span class="line">        <span class="comment">//4. 创建结果持有属性</span></span><br><span class="line">        AtomicBoolean finished = <span class="keyword">new</span> AtomicBoolean(<span class="keyword">false</span>);</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//2. 由于要将执行结果以Future返回，所以该方法内部应持有一个Future</span></span><br><span class="line">        Future&lt;T&gt; future = <span class="keyword">new</span> Future&lt;T&gt;() &#123;</span><br><span class="line">            <span class="comment">//内部持有回调接口，即类似js回调函数</span></span><br><span class="line">            <span class="keyword">private</span> Completable&lt;T&gt; completable;</span><br><span class="line">            </span><br><span class="line">            <span class="comment">//3. 内部类可以取到外面的属性，所有在外面创建Atomic类型</span></span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> T <span class="title">get</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                <span class="keyword">return</span> result.get();</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isDone</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                <span class="keyword">return</span> finished.get();</span><br><span class="line">            &#125;</span><br><span class="line">            </span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setCompletable</span><span class="params">(Completable&lt;T&gt; completable)</span> </span>&#123;</span><br><span class="line">                <span class="keyword">this</span>.completable = completable;</span><br><span class="line">            &#125;</span><br><span class="line">            </span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> Completable&lt;T&gt; <span class="title">getCompletable</span><span class="params">()</span></span>&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">this</span>.completable;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//1. 开启一个线程异步执行业务逻辑</span></span><br><span class="line">        Thread t = <span class="keyword">new</span> Thread(()-&gt;&#123;</span><br><span class="line">            <span class="keyword">try</span>&#123;</span><br><span class="line">                T value = callable.action();</span><br><span class="line">            	result.set(value);</span><br><span class="line">            	finished.set(<span class="keyword">true</span>);</span><br><span class="line">                <span class="keyword">if</span>(future.getCompletable != <span class="keyword">null</span>)&#123;</span><br><span class="line">                    future.getCompletable.complete(value);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span>(Throwable cause)&#123;</span><br><span class="line">                <span class="keyword">if</span>(future.getCompletable != <span class="keyword">null</span>)&#123;</span><br><span class="line">                    future.getCompletable.exception(cause);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        </span><br><span class="line">        <span class="comment">//5. 执行线程</span></span><br><span class="line">        t.start();</span><br><span class="line">        <span class="keyword">return</span> future;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Future</span>&lt;<span class="title">T</span>&gt;</span>&#123;</span><br><span class="line">        <span class="function">T <span class="title">get</span><span class="params">()</span></span>;</span><br><span class="line">        <span class="function"><span class="keyword">boolean</span> <span class="title">isDone</span><span class="params">()</span></span>;</span><br><span class="line">        <span class="function"><span class="keyword">void</span> <span class="title">setCompletable</span><span class="params">(Completable&lt;T&gt; completable)</span></span>;</span><br><span class="line">        <span class="function">Completable&lt;T&gt; <span class="title">getCompletable</span><span class="params">()</span></span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//外部业务逻辑执行接口</span></span><br><span class="line">    <span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Callable</span>&lt;<span class="title">T</span>&gt;</span>&#123;</span><br><span class="line">        <span class="function">T <span class="title">action</span><span class="params">()</span></span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//外部接收通知的回调接口，它的实现将被持有到future内部属性中</span></span><br><span class="line">    <span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Completable</span>&lt;<span class="title">T</span>&gt;</span>&#123;</span><br><span class="line">        <span class="function"><span class="keyword">void</span> <span class="title">complete</span><span class="params">(T t)</span></span>;</span><br><span class="line">        <span class="function"><span class="keyword">void</span> <span class="title">exception</span><span class="params">(Throwable cause)</span></span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> InterruptedException </span>&#123;</span><br><span class="line">        <span class="comment">//外部的业务逻辑</span></span><br><span class="line">        Future&lt;String&gt; future = invoke(() -&gt; &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                Thread.sleep(<span class="number">1000L</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="string">"I am Finished."</span>;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">                <span class="keyword">return</span> <span class="string">"I am Error."</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="comment">//实现回调接口</span></span><br><span class="line">        future.setCompletable(<span class="keyword">new</span> Completable&lt;String&gt;()&#123;</span><br><span class="line">            </span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">complete</span><span class="params">(T t)</span></span>&#123;</span><br><span class="line">                System.out.println(t);</span><br><span class="line">            &#125;</span><br><span class="line">            </span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">        	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">exception</span><span class="params">(Throwable cause)</span></span>&#123;</span><br><span class="line">            	System.out.println(cause);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        System.out.println(future.get());</span><br><span class="line">        System.out.println(future.get());</span><br><span class="line">        System.out.println(future.get());</span><br><span class="line">        Thread.sleep(<span class="number">2000L</span>);</span><br><span class="line">        System.out.println(future.get());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


    </div>

    <div>全文完。</div>
  </article>
  <div class="toc-container">
    
  <div id="toc" class="toc-article">
    <strong class="toc-title">目录</strong>
    <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#future的简单实现"><span class="toc-text">future的简单实现</span></a></li></ol>
  </div>


  </div>
</div>

<div class="share" style="width: 100%;">
  <div class="text-center">
    人生若只如初见，何事秋风悲画扇。
  </div> 
</div>

  
    <div class="post-nav">
      <div class="post-nav-item post-nav-next">
        
          <span>〈 </span>
          <a href="/2020/07/07/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" rel="next" title="设计模式">
          设计模式
          </a>
        
      </div>
  
      <div class="post-nav-item post-nav-prev">
          
      </div>
    </div>
  

    </div>

    
    <div id="toTop">^</div>
  </div>
  <footer class="footer text-center">
    <div id="bottom-inner">
        <a class="bottom-item" href="https://lustghost.gitee.io">首页</a> |
        <a class="bottom-item" href="https://github.com/haige2486" target="_blank">GitHub</a> |
        <a class="bottom-item" href="https://hexo.io" target="_blank">Powered by hexo</a>
    </div>
</footer>
  

<script>
  var pjax = new Pjax({
    elements: "a",
    selectors: [".inner"]
  });

  document.addEventListener('visibilitychange', function () {
    if (document.visibilityState == 'hidden') {
      normal_title = document.title;
      document.title = 'დ待゜人归ꦿ໊ོﻬ࿐ོ';
    } else document.title = normal_title;
  });

  function rt() {
    var d = document,
      dd = document.documentElement,
      db = document.body,
      top = dd.scrollTop || db.scrollTop,
      step = Math.floor(top / 20);
    (function () {
      top -= step;
      if (top > -step) {
        dd.scrollTop == 0 ? db.scrollTop = top : dd.scrollTop = top;
        setTimeout(arguments.callee, 20);
      }
    })();
  }
  document.getElementById("toTop").addEventListener("click", rt);
  document.addEventListener("scroll", function () {
    var dd = document.documentElement,
      db = document.body,
      top = dd.scrollTop || db.scrollTop
    if (top > (window.innerHeight*0.7)) {
      document.getElementById("toTop").style.display = "block";
      document.getElementsByClassName("nav-container")[0].style.display = "none";
    } else {
      document.getElementById("toTop").style.display = "none";
    }
    if(top<50){
      document.getElementsByClassName("nav-container")[0].style.display = "block";
    }
  })
</script>
  



  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">
<script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<!-- require MetingJS -->
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>
<meting-js  id="2660651585"  server="netease"  type="playlist"  fixed="true"  autoplay="false"  loop="all"  order="random"  preload="auto"  volume="0.7"  mutex="true"  </meting-js>
    <style id="rewrite">
        .aplayer.aplayer-fixed{
            width: 70%;
        }
        .aplayer-body{
            width: 80% !important;
        }
        .aplayer.aplayer-narrow .aplayer-body {
            left: -66px !important;
        }
        .aplayer.aplayer-fixed .lrc-show {
            display: block;
            background: rgba(255, 255, 255, 0.8);
        }
        .aplayer-lrc-current{
            animation: shake-it .5s reverse infinite cubic-bezier(0.68, -0.55, 0.27, 1.55);
        }
    </style>
    <script>
        typeof document.getElementsByClassName("aplayer")[0] !== "undefined" && document.getElementsByClassName("aplayer")[0].addEventListener("click", function () {
            if (document.getElementsByClassName("aplayer-button")[0].hasClass('aplayer-play')) {
                document.getElementsByClassName('aplayer-lrc')[0].removeClass('lrc-show');
            } else {
                document.getElementsByClassName('aplayer-lrc')[0].addClass('lrc-show');
            }
        })
    </script>
</body>
</html>
